package com.wy2.eclipse.tool.lib.neoodb;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.neodatis.odb.ODB;
import org.neodatis.odb.ODBFactory;
import org.neodatis.odb.Objects;
import org.neodatis.odb.core.query.IQuery;
import org.neodatis.odb.core.query.criteria.ICriterion;
import org.neodatis.odb.impl.core.query.criteria.CriteriaQuery;
import org.neodatis.odb.impl.core.query.criteria.EqualCriterion;
import com.wy2.core.tool.StringTools;

public class Session  implements AutoCloseable{

	/**
	 * 数据库位置
	 */
	private final File dbPath;
	
	private ODB odb=null;
	
	
	
	
	public File getDbPath() {
        return dbPath;
    }

    public ODB getOdb() {
        return odb;
    }

    public Session(File dbPath) {
		super();
		this.dbPath = dbPath;
	}

	public void open() {
		if(odb==null || odb.isClosed()) {
			odb=ODBFactory.open(dbPath.getAbsolutePath());
		}
	}
	
	public <T extends EntityBase> void add(Class<T> clazz,T obj) throws OdbException {
	    if(obj==null || StringTools.isEmpty(obj.getObjId())) {
	        throw new OdbException("插入的对象为空");
	    }
		open();		
		odb.store(obj);
	}
	
	public <T extends EntityBase> void update(Class<T> clazz,T obj) throws OdbException{
	    if(obj==null || StringTools.isEmpty(obj.getObjId())) {
            throw new OdbException("更新的对象为空");
        }
	    open();
	    IQuery query = new CriteriaQuery(clazz, new EqualCriterion("objId", obj.getObjId(), false));
        Objects<T> objs = odb.getObjects(query);
        if(objs.hasNext()) {
            T oldData = objs.next();
            odb.delete(oldData);
            odb.store(obj);
        }else {
            throw new OdbException("要更新的对象不存在");
        }	    
	}
	
	/*
	 * 根据objId判断，是否存在
	 */
	public <T extends EntityBase> void addOrUpdate(Class<T> clazz,T obj) throws OdbException{
        if(obj==null || StringTools.isEmpty(obj.getObjId())) {
            throw new OdbException("操作对象为空");
        }
        open();
        IQuery query = new CriteriaQuery(clazz, new EqualCriterion("objId", obj.getObjId(), false));
        Objects<T> objs = odb.getObjects(query);
        if(objs.hasNext()) {
            //存在更新
            T oldData = objs.next();
            odb.delete(oldData);
            odb.store(obj);
        }else {
            //不存在新增
            odb.store(obj);
        }
        
    }
	
	
	public <T extends EntityBase> void delete(Class<T> clazz,String objId) throws OdbException{
        if(StringTools.isEmpty(objId)) {
            throw new OdbException("删除的对象为空");
        }
        open();
        IQuery query = new CriteriaQuery(clazz, new EqualCriterion("objId", objId, false));
        Objects<T> objs = odb.getObjects(query);
        while(objs.hasNext()) {
            T oldData = objs.next();
            odb.delete(oldData);
        }
        odb.commit();
    }
	public <T extends EntityBase> void delete(Class<T> clazz,T obj) throws OdbException{
	    if(obj==null || StringTools.isEmpty(obj.getObjId())) {
            throw new OdbException("删除的对象为空");
        }
        open();
        IQuery query = new CriteriaQuery(clazz, new EqualCriterion("objId", obj.getObjId(), false));
        Objects<T> objs = odb.getObjects(query);
        while(objs.hasNext()) {
            T oldData = objs.next();
            odb.delete(oldData);
        }
        odb.commit();
	}
	
	public void commit() {
	    open();
	    odb.commit();
	}

	public  <T extends EntityBase> List<T> findAll(Class<T> clazz){
	    IQuery query = new CriteriaQuery(clazz);
	    return findAll(clazz, query);
	}
	public  <T extends EntityBase> List<T> findAll(Class<T> clazz,IQuery query){
	    open();	    
        Objects<T> objs = odb.getObjects(query);
        List<T> list=new ArrayList<>();
        T tempObj=null;
        while(objs.hasNext()) {
            tempObj = objs.next();
            list.add(tempObj);
        }
        return list;
	}
	public  <T extends EntityBase> List<T> findAll(Class<T> clazz,ICriterion criteria){
        open();     
        IQuery query = new CriteriaQuery(clazz, criteria);
        Objects<T> objs = odb.getObjects(query);
        List<T> list=new ArrayList<>();
        T tempObj=null;
        while(objs.hasNext()) {
            tempObj = objs.next();
            list.add(tempObj);
        }
        return list;
    }
	
	public  <T extends EntityBase> List<T> findAll(Class<T> clazz,String objId){
	    ICriterion criteria=new EqualCriterion("objId", objId, false);
        IQuery query = new CriteriaQuery(clazz, criteria);
        return findAll(clazz, query);
    }
	
	public  <T extends EntityBase> T find(Class<T> clazz,ICriterion criteria){
        open();     
        IQuery query = new CriteriaQuery(clazz, criteria);
        Objects<T> objs = odb.getObjects(query);
        T tempObj=null;
        if(objs.hasNext()) {
            tempObj = objs.next();
        }
        return tempObj;
    }


	@Override
	public void close() throws Exception {
		if(odb!=null && !odb.isClosed()) {
			odb.close();
		}
		odb=null;		
	}

}
